#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <omp.h>

#define STRSIZE 45
#define NTHREAD 2

void clear_str(char *c, int n);

int main(int argc, char *argv[]) {

    FILE *fp;
    char aux[STRSIZE];
    char **text = (char**)malloc(sizeof(char*));
    char *frase = (char*)malloc(sizeof(char));
    int i = 0;
    int j = 0;
    int n = 0;
    int pa = 0;
    int chunk = 0;
    int pf=0;
    int tamanho_frase=0;
    int n_frase=0;

    if ( (fp = fopen(argv[1],"r")) == NULL ) {
        printf("Erro ao abrir o arquivo.\n");
        exit(1);
    }

    omp_set_num_threads(NTHREAD);

    clear_str(aux,STRSIZE);

    while(!feof(fp)) {

        fscanf(fp,"%s",aux);
        //printf("%s\n",aux);
        text = (char**)realloc(text,sizeof(char*)*(n+1));
        text[i] = (char*)malloc(sizeof(char)*(strlen(aux)+1));
        strcpy(text[i],aux);
        clear_str(aux,STRSIZE);
        n++;
        i++;
    }

    chunk = n/NTHREAD >= 1 ? n/NTHREAD : 1;
    
    #pragma omp parallel shared(text,chunk,n) firstprivate(i) reduction(+:pa)
    {
        #pragma omp for schedule(dynamic,chunk) nowait
        for ( i = 0; i < n-1; i++ ) {
            pa += palindromo(text[i]);
            
        }
    }

    ///monta matriz de frases
    tamanho_frase=1;
    clear_str(frase,tamanho_frase);     
    for(i=0; i< n-1; i++ )
    {
       tamanho_frase+=strlen(text[i]);
       frase=(char*)realloc(frase,sizeof(char)*tamanho_frase);
       strcat(frase,text[i]);  
      // printf("palavra: %s\n",text[i]);
       clear_str(text[i],strlen(text[i]));
       text[i]= (char*)realloc(text[i],sizeof(char)*1); //diminue o espaço na memoria, free aqui da erro
       if(frase[strlen(frase)-1]=='.' || frase[strlen(frase)-1]==':' || frase[strlen(frase)-1]=='?' || frase[strlen(frase)-1]=='!')
           {
                text[n_frase] = (char*)realloc(text[n_frase],sizeof(char)*tamanho_frase);
                strcat(text[n_frase],frase);
                n_frase++;
                clear_str(frase,tamanho_frase);         
                tamanho_frase=1;
           }        
    }

    #pragma omp parallel shared(text,chunk,n_frase) firstprivate(i) reduction(+:pf)
    {
        #pragma omp for schedule(dynamic,chunk) nowait
        for ( i = 0; i < n_frase -1; i++ ) {
            pf += palindromo(text[i]);
           
            
        }
    }



    printf("Palindromo de Palavra: %d\n",pa);
    printf("Palindromo de Frase: %d\n",pf);
    free(*text);
    free(text);
    fclose(fp);

    fflush(stdout);


    return 0;

}

void clear_str(char *c, int n) {

    int i = 0;

    for ( i = 0; i < n; i++ ) {
        c[i] = 0;
    }

}

int palindromo(char *str) {

    int i,l,j;
    int ssize = strlen(str);

    i=0;
    j=ssize-1;
    //ignorando caracteres especiais no final de palavra, no final da palavra, exem.: (kfbrwiufh)
    for(l=j;l>=0;l--)
        if((int)str[l]<65 || ((int)str[l]>90 && (int)str[l]<97) || (int)str[l]>122 )
	{
		if(str[l]==',')
			str[l]=0;
                j--;
	}
        else
                break;

    //ignorando caracteres especiais no inicio de palavra, no final da palavra, exem.: (kfbrwiufh)
    for(l=0;l<=j;l++)
        if((int)str[l]<65 || ((int)str[l]>90 && (int)str[l]<97) || (int)str[l]>122 )
                i++;
        else
                break;
    
    //se passar aq é palimdrome
    if(j==-1)
        return 0;//isso significa e existe uma palavra com apenas simbolos especiais
    for (  ;i < j;i++){
        if (   ((int)str[j] != (int)str[i])   &&         ((int)str[j]+32 != (int)str[i])   && ((int)str[j] != (int)str[i]+32)         )
                return 0;
        j--;
    }
    //printf("%s ",str);
    return 1;

}
